package com.ma.api;

import com.ma.entity.dto.MovieInfo;
import com.ma.tools.AITools;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.api.Advisor;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.model.Generation;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.converter.BeanOutputConverter;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.ai.deepseek.DeepSeekChatOptions;
import org.springframework.ai.deepseek.api.DeepSeekApi;
import org.springframework.ai.document.Document;
import org.springframework.ai.rag.advisor.RetrievalAugmentationAdvisor;
import org.springframework.ai.rag.retrieval.search.VectorStoreDocumentRetriever;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.zhipuai.ZhiPuAiChatModel;
import org.springframework.ai.zhipuai.ZhiPuAiChatOptions;
import org.springframework.ai.zhipuai.ZhiPuAiEmbeddingModel;
import org.springframework.ai.zhipuai.api.ZhiPuAiApi;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * DeepSeekChatApi is a REST controller for DeepSeek chat API.
 */
@RequiredArgsConstructor
@RestController
@RequestMapping("/chat")
public class ChatApi {

    private final DeepSeekChatModel deepSeekChatModel;

    private final ZhiPuAiChatModel zhiPuAiChatModel;

    private final ZhiPuAiEmbeddingModel zhiPuAiEmbeddingModel;

    private final AITools tools;

    private final static List<Document> documents = List.of(new Document("第一章（架构概述）:\n" +
                    "Spring Boot 微服务架构由多个独立可部署的服务组成，通过 API Gateway 统一入口，注册中心进行服务发现。每个服务都保持高内聚低耦合，并使用独立数据库。"),
            new Document("第二章（服务注册与配置）:\n" +
                    "在注册中心（例如 Nacos、Eureka）中，服务在启动时会将自身信息注册进去，实现动态发现。配置中心（如 Spring Cloud Config 或 Nacos Config）用于集中管理服务配置，支持配置热更新。"),
            new Document("第三章（网关与负载均衡）:\n" +
                    "API Gateway（如 Spring Cloud Gateway）作为流量入口，负责路由转发、鉴权和限流。负载均衡（Ribbon 或 Spring Cloud LoadBalancer）在多个实例间分配请求，保证系统可用性。"),
            new Document("第四章（容器化与部署）:\n" +
                    "服务打包成 Docker 镜像，通过 Kubernetes 或 Docker Compose 管理部署。K8s Deployment 控制服务副本数、滚动更新与自动恢复。Service 对象用于服务暴露，Ingress 实现外部访问。"),
            new Document("第五章（日志与监控）:\n" +
                    "使用 ELK（Elasticsearch + Logstash + Kibana）或 Loki + Promtail + Grafana 构建日志与指标系统。Spring Boot Actuator 提供健康检查与监控端点，可集成 Prometheus 采集数据。"),
            new Document("第六章（持续集成与交付）:\n" +
                    "通过 Jenkins、GitLab CI 或 GitHub Actions 构建自动化流水线。流水线包括代码检查、单元测试、构建、镜像推送与部署步骤，实现自动化 DevOps。"));


    @GetMapping("/simple/dp")
    public ChatResponse dpGenerate(@RequestParam(value = "query", defaultValue = "你好，很高兴认识你，介绍下你自己！") String query) {
        System.out.println("收到消息：" + query);
        // 动态设置 ChatModel 的 Options 参数
        DeepSeekChatOptions promptOptions = DeepSeekChatOptions.builder()
                .model(DeepSeekApi.ChatModel.DEEPSEEK_REASONER.getValue())
                .build();
        ChatResponse call = deepSeekChatModel.call(new Prompt(query, promptOptions));
        System.out.println("收到回复：" + call.getResult());
        return call;
    }

    /**
     * chat
     *
     * @param query query
     * @return ChatResponse
     */
    @GetMapping("/simple/zp")
    public ChatResponse zpGenerate(@RequestParam(value = "query", defaultValue = "你好，很高兴认识你，介绍下你自己！") String query) {
        System.out.println("收到消息：" + query);
        // 动态设置 ChatModel 的 Options 参数
        ZhiPuAiChatOptions promptOptions = ZhiPuAiChatOptions.builder()
                .model(ZhiPuAiApi.ChatModel.GLM_4V.getValue())
                .build();
        ChatResponse call = zhiPuAiChatModel.call(new Prompt(query, promptOptions));
        System.out.println("收到回复：" + call.getResult());
        return call;
    }

    /**
     * 结构化输出
     *
     * @param title 标题
     * @return MovieInfo
     */
    @GetMapping("/movieInfo/zp")
    public MovieInfo movieInfo(@RequestParam(value = "title", defaultValue = "星际穿越") String title) {
        // 创建 converter
        BeanOutputConverter<MovieInfo> converter = new BeanOutputConverter<>(MovieInfo.class);
        String format = converter.getFormat();

        // 构建 prompt 模板
        String template = """
                给出关于电影 "{movieTitle}" 的信息。
                输出必须是 JSON 格式，符合以下结构：{format}
                """;

        Generation generation = zhiPuAiChatModel.call(
                PromptTemplate.builder().template(template).variables(Map.of("movieTitle", title, "format", format))
                        .build().create()).getResult();
        return converter.convert(Objects.requireNonNull(generation.getOutput().getText()));
    }

    /**
     * embed
     */
    @GetMapping("/embed/zp")
    public void search() {

        // 示例文本
        String text = """
                第一章（架构概述）:
                Spring Boot 微服务架构由多个独立可部署的服务组成，通过 API Gateway 统一入口，注册中心进行服务发现。每个服务都保持高内聚低耦合，并使用独立数据库。
                """;

        // 调用智谱Embedding模型
        List<float[]> response = zhiPuAiEmbeddingModel.embed(List.of(text));
        // 获取向量
        float[] vector = response.getFirst();
        System.out.println("✅ 向量维度：" + vector.length);
        System.out.println("✅ 向量前10个值：");
        for (int i = 0; i < 10 && i < vector.length; i++) {
            System.out.print(vector[i] + " ");
        }
    }


    /**
     * Tools Calling
     *
     * @return String
     */
    @GetMapping("/tool/zp")
    public String tools(@RequestParam(value = "userId") String userId, @RequestParam(value = "productId") String productId) {

        // 构建工具调用参数
        String query = "我是 " + userId + "，想买商品 " + productId + " ，" +
                "下单前先告诉我库存情况，如果有库存，请帮我下单 2件，";

        System.out.println("收到消息：" + query);

        String response = ChatClient.create(zhiPuAiChatModel)
                .prompt(query)
                .tools(tools) // 设置工具
                .toolContext(Map.of("tenantId", "T-ACME"))  // 设置工具上下文
                .call()
                .content();
        System.out.println("收到回复：" + response);
        return response;
    }


    @GetMapping("/ask/zp")
    public String ask(@RequestParam("query") String query) {

        SimpleVectorStore simpleVectorStore = SimpleVectorStore.builder(zhiPuAiEmbeddingModel).build();
        simpleVectorStore.add(documents);

        // 1. 检索最相似的文档
        SearchRequest build = SearchRequest.builder().query(query).build();
        List<Document> documents = simpleVectorStore.similaritySearch(build);
        System.out.println("检索到最相似的文档：" + documents);

        return documents.toString();
    }
}